﻿
Imports System.IO
Imports System.Threading
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Drawing.Imaging

#If Not PocketPC AndAlso Not Smartphone Then
Public Class webBrowserDrawer2

    Public Const maxWaitTime As Int64 = 60 * 1000
#If RETIRED Then
    Private mutex As Mutex = Nothing
#End If
    Private bmp As Bitmap = Nothing
    Private format As ImageFormat = ImageFormat.Bmp
    Private stream As Stream = Nothing
    Private finished As Boolean = True
    Private statusCode As Int64 = 0
    Private destinationSize As Size = Nothing

    Public Function busy() As Boolean
        Return Not finished
    End Function

    <Security.Permissions.PermissionSet(Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
    Private Sub browser_DocumentCompleted(ByVal sender As Object, _
                                          ByVal e As WebBrowserDocumentCompletedEventArgs) _
                                         Handles browser.DocumentCompleted
        If strsame(Convert.ToString(browser.Url), network.ieBlankPage, False) Then
            Return
        End If
        'assert(Not stream Is Nothing AndAlso stream.CanWrite(), "should not navigate without request.")
        If Not stream Is Nothing AndAlso stream.CanWrite() Then
            Dim internalFinished As Boolean
            internalFinished = strsame(e.Url.ToString(), browser.Url.ToString()) AndAlso _
                               browser.ReadyState = WebBrowserReadyState.Complete AndAlso _
                               Not browser.IsBusy()
            If internalFinished Then
                browser.Stop()
                Application.DoEvents()
            End If
            If bmp Is Nothing OrElse bmp.Size() <> browser.Size() Then
                If Not bmp Is Nothing Then
                    bmp.Dispose()
                End If
                bmp = New Bitmap(browser.Size().Width, browser.Size().Height)
            End If
            Dim drawRect As New Rectangle(New Point(0, 0), browser.Size)
            browser.DrawToBitmap(bmp, drawRect)
            stream.SetLength(0)
            If destinationSize <> browser.Size() Then
                Dim bmp2 As Image = Nothing
                bmp2 = graphUtils.resizeImage(bmp, destinationSize)
                If Not bmp2 Is Nothing Then
                    bmp2.Save(stream, format)
                    bmp2.Dispose()
                End If
            Else
                bmp.Save(stream, format)
            End If
            stream.Flush()
            If internalFinished Then
                finished = True
            End If
        End If
    End Sub

    Public Function save(ByVal url As String, ByRef stream As Stream, ByVal format As ImageFormat, _
                         ByVal size As Size, ByVal destinationSize As Size) As Boolean
#If RETIRED Then
        assert(Mutex.WaitOne(), "cannot lock mutex when save browserDraw.")
#End If
        Dim rtn As Boolean = False
        Dim backupStatusCode As Int64
        SyncLock browser
            Dim startTime As Int64
            startTime = ticksToMilliseconds(Now.Ticks)
            finished = False
            statusCode = 0
            If stream Is Nothing Then
                stream = New MemoryStream()
            End If
            If isdebugmode() Then
                raiseError("save webpage to stream, url = " + url + ", format = " + format.ToString)
            End If
            Me.stream = stream
            browser.Size = size
            Me.destinationSize = destinationSize
            Me.Text = "webBrowserDrawer2 - " + url
            Me.format = format

            browser.Navigate(url)
            While Not finished AndAlso ticksToMilliseconds(Now.Ticks()) - startTime < maxWaitTime
                Application.DoEvents()
                sleep(64)
            End While
            If Not finished Then
                browser.Stop()
                Application.DoEvents()

                If Not finished Then
                    raiseError("cannot save webpage to stream in maxWaittime, url = " + url, errorHandle.errorType.user)
                End If
            End If
            browser.Navigate(network.ieBlankPage)
            Application.DoEvents()

            rtn = (statusCode = 0)
            If Not rtn Then
                backupStatusCode = statusCode
            End If
        End SyncLock
#If RETIRED Then
        Mutex.ReleaseMutex()
#End If

        If Not rtn Then
            raiseError("cannot save webpage to stream, url = " + url + ", error statusCode = " _
                       + Convert.ToString(backupStatusCode), errorHandle.errorType.user)
        End If
        Return rtn
    End Function

    Public Function save(ByVal url As String, ByVal filename As String, ByVal format As ImageFormat, _
                         ByVal size As Size, ByVal destinationSize As Size) As Boolean
        On Error Resume Next
        Dim file As FileStream
        If isdebugmode() Then
            raiseError("save webpage to file, url = " + url + ", fileName = " + filename + _
                        ", format = " + format.ToString)
        End If
        file = New FileStream(filename, FileMode.Create)
        If file Is Nothing Then
            raiseError("failed to create fileStream, check fileName, " + filename, errorHandle.errorType.exclamation)
            Return False
        Else
            Dim rtn As Boolean = False
            rtn = save(url, file, format, size, destinationSize)
            file.Close()

            Return rtn
        End If
    End Function

    Public Function save(ByVal url As String, ByRef stream As Stream, _
                         ByVal size As Size, ByVal destinationSize As Size) As Boolean
        Return save(url, stream, ImageFormat.Jpeg, size, destinationSize)
    End Function

    Public Function save(ByVal url As String, ByVal fileName As String, _
                         ByVal size As Size, ByVal destinationSize As Size) As Boolean
        Return save(url, fileName, ImageFormat.Jpeg, size, destinationSize)
    End Function

    Public Shared Function generateSize(Optional ByVal width As Int64 = npos, _
                                        Optional ByVal height As Int64 = npos) As Size
        If width = npos Then
            width = 1024
        End If
        If height = npos Then
            height = 768
        End If

        Return New Size(width, height)
    End Function

    Public Function save(ByVal url As String, ByRef stream As Stream, _
                         Optional ByVal width As Int64 = npos, Optional ByVal height As Int64 = npos, _
                         Optional ByVal destinationWidth As Int64 = npos, _
                         Optional ByVal destinationHeight As Int64 = npos) As Boolean
        Return save(url, stream, generateSize(width, height), generateSize(destinationWidth, destinationHeight))
    End Function

    Public Function save(ByVal url As String, ByVal filename As String, _
                         Optional ByVal width As Int64 = npos, Optional ByVal height As Int64 = npos, _
                         Optional ByVal destinationWidth As Int64 = npos, _
                         Optional ByVal destinationHeight As Int64 = npos) As Boolean
        Return save(url, filename, generateSize(width, height), generateSize(destinationWidth, destinationHeight))
    End Function

    Private Sub browser_NavigateError(ByVal disp As Object, ByRef url As Object, ByRef frame As Object, _
                                      ByRef statusCode As Object, ByRef cancel As Boolean) _
                                      Handles browser.NavigateError
        If strsame(Convert.ToString(url), browser.Url().ToString(), False) Then
            Me.statusCode = statusCode
        End If
        cancel = True
    End Sub

    Private Sub browser_NewWindow(ByVal sender As Object, _
                                  ByVal e As System.ComponentModel.CancelEventArgs) Handles browser.NewWindow
        e.Cancel = True
    End Sub

    Private Sub webBrowserDrawer2_FormClosing(ByVal sender As Object, _
                                              ByVal e As FormClosingEventArgs) _
                                             Handles Me.FormClosing
        If e.CloseReason = CloseReason.UserClosing Then
            e.Cancel = True
        Else
            If Not bmp Is Nothing Then
                bmp.Dispose()
            End If
            assert(Not browser Is Nothing, "browser is manually set to nothing before form close.")
            browser.Stop()
#If RETIRED Then
            assert(Not mutex Is Nothing, "mutex is manully set to nothing before form close.")
            mutex.Close()
#End If
        End If
    End Sub
End Class
#End If
